/******************************************************************************
 * Copyright (C) 2011 ShenZhen ComTop Information Technology Co.,Ltd
 * All Rights Reserved.
 * 本软件为深圳康拓普开发研制。未经本公司正式书面同意，其他任何个人、团体不得使用、
 * 复制、修改或发布本软件.
 *****************************************************************************/

package com.code.common.excel.officeexport.excel.tag;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;

import com.code.common.excel.officeexport.excel.exception.ExportExcelException;


/**
 * excel导出的工具类
 * 
 * @author 李广
 * @since 1.0
 * @version 2011-8-29 李广
 */
public final class ExcelUtil {
    
    /**
     * 构造函数
     */
    private ExcelUtil() {
    }
    
    /**
     * 获得标签中关键字对应的值.
     * 
     * <pre>
     *    例如标签为: &quot;&lt; object name=objName method=getMethod &gt;&quot;
     *    String tagString = &quot;&lt; object name=objName method=getMethod &gt;&quot;;
     *    String name = &quot;method&quot;;
     *    getKeyWord(tagString,name); -- 这将返回 &quot;getMethod&quot;
     * </pre>
     * 
     * @param tag 标签
     * @param name 关键字
     * @return 关键字对应的值
     */
    public static String getKeyWord(String tag, String name) {
        String strTag = tag.replaceAll(">", " ").toLowerCase();
        int iBegin = strTag.indexOf(name.toLowerCase()) + name.length() + 1;
        String strIndexOfChar = " ";
        int iEnd = strTag.indexOf(strIndexOfChar, iBegin);
        return tag.substring(iBegin, iEnd);
    }
    
public static void main(String[] args) {
	System.out.println(getKeyWord("<iterator name=list method=getTitle>","name"));
}
    
    /**
     * 获得指定模板sheet中的指定标签的位置信息和style信息.
     * 
     * @param sheet 指定的sheet
     * @param tagName 指定的标签
     * @return 模板中标签的信息.
     */
    public static Map<String, List<ExcelCell>> getAllTag(HSSFSheet sheet, List<String> tagName) {
        Map<String, List<ExcelCell>> objResult = initTageType(tagName);
        List<ExcelCell> lstTag = null;
        HSSFRow objRow;
        HSSFCell objCell;
        String strTage = null;
        String strType = null;
        int iLastCellNum;
        int iLastRowNum = sheet.getLastRowNum();
        
        for (int i = 0; i <= iLastRowNum; i++) {
            objRow = sheet.getRow(i);
            if (objRow == null) {
                continue;
            }
            iLastCellNum = objRow.getLastCellNum();
            for (int j = 0; j < iLastCellNum; j++) {
                objCell = objRow.getCell(j);
                if (objCell != null && objCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                    strTage = objCell.getStringCellValue();
                    strType = getType(strTage);
                    if (strType != null) {
                        lstTag = objResult.get(strType);
                        if (lstTag != null) {
                            ExcelCell objExcelCell = new ExcelCell();
                            objExcelCell.setRowno(i);
                            objExcelCell.setRowHeight(objRow.getHeightInPoints());
                            objExcelCell.setCellno((short) j);
                            objExcelCell.setStyle(objCell.getCellStyle());
                            objExcelCell.setTagStr(strTage);
                            lstTag.add(objExcelCell);
                        }
                    }
                    
                }
            }
        }
        return objResult;
    }
    
    /**
     * 根据对象和对象的方法的名称来调用对象的方法.
     * 
     * @param object 指定的对象.
     * @param methodName 对象方法的名称.
     * @return 调用的对象的方法返回的值.
     * @throws ExportExcelException 调用对象方法时的异常.
     */
    public static Object getValue(Object object, String methodName) throws ExportExcelException {
        try {
            Method objMethod = object.getClass().getMethod(methodName, new Class[0]);
            return invokeMethod(objMethod, object, new Object[0]);
        } catch (SecurityException e) {
            throw new ExportExcelException(e.toString(), e);
        } catch (NoSuchMethodException e) {
            throw new ExportExcelException(e.toString(), e);
        }
    }
    
    /**
     * 根据对象和对象方法的名称调用指定对象的方法.
     * 
     * @param methodClass 类的方法
     * @param object 对象
     * @param objectArrays 对象数组
     * @return 对象
     * @throws ExportExcelException 
     */
    private static Object invokeMethod(Method methodClass, Object object, Object[] objectArrays) throws ExportExcelException {
        if (object == null || objectArrays == null || methodClass == null) {
            throw new IllegalArgumentException("传递过来的参照值无效，请检查参数对象是否为空值!");
        }
        if (!Modifier.isPublic(methodClass.getModifiers())) {
            throw new IllegalArgumentException("指定的方法不是Public的方法，请核对后重新检查,您设置的条件也许不正确!");
        }
        Object objValue = null;
        try {
            objValue = methodClass.invoke(object, objectArrays);
        } catch (InvocationTargetException e) {
            throw new ExportExcelException(e.toString(), e);
        } catch (IllegalAccessException e) {
            throw new ExportExcelException(e.toString(), e);
        }
        return objValue;
    }
    
    /**
     * 在getAllTag方法中调用,初始化存放标签信息的HashMap.
     * 
     * @param tagName 标签
     * @return 存放标签的map
     */
    private static Map<String, List<ExcelCell>> initTageType(List<String> tagName) {
        Map<String, List<ExcelCell>> objMapResult = new HashMap<String, List<ExcelCell>>();
        int iSize = tagName.size();
        List<ExcelCell> lstNew;
        for (int i = 0; i < iSize; i++) {
            lstNew = new ArrayList<ExcelCell>();
            objMapResult.put(tagName.get(i), lstNew);
        }
        return objMapResult;
    }
    
    /**
     * 获得标签的类型信息
     * 
     * <pre>
     * 如标签为 &quot; &lt; object name=someName method=getMethod &gt; &quot; 这将返回 : &quot;object&quot;.
     * </pre>
     * 
     * @param str 字符串
     * @return 标签类型
     */
    private static String getType(String str) {
        String strIndexOfChar = "<";
        if (str.indexOf(strIndexOfChar) > -1) {
            String strTagName = str.replaceAll("<", " ").trim();
            strIndexOfChar = " ";
            int iPosi = strTagName.indexOf(strIndexOfChar);
            if (iPosi < 0) {
                return null;
            }
            return strTagName.substring(0, iPosi);
        }
        return null;
    }
    
}
